package com.geekhole.demo.v2;

import com.geekhole.demo.app.order.Order;
import com.geekhole.demo.app.order.OrderApplication;
import com.geekhole.demo.app.order.OrderItem;
import com.geekhole.demo.app.product.Product;
import com.geekhole.demo.app.product.ProductApplication;
import com.geekhole.demo.app.shop.Shop;
import com.geekhole.demo.app.shop.ShopApplication;
import com.geekhole.demo.app.user.User;
import com.geekhole.demo.app.user.UserApplication;
import com.geekhole.demo.view.OrderItemView;
import com.geekhole.demo.view.OrderView;
import com.geekhole.demo.view.OrderViewApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class OrderViewV2Application implements OrderViewApplication {
    @Autowired
    private UserApplication userApplication;
    @Autowired
    private ShopApplication shopApplication;
    @Autowired
    private ProductApplication productApplication;
    @Autowired
    private OrderApplication orderApplication;

    @Override
    public List<OrderView> getByUserId(Long userId) {
        List<OrderView> orderViews = new ArrayList<>();

        List<Order> orders = orderApplication.getByUser(userId);

        List<Long> userIds = orders.stream()
                .map(Order::getUserId)
                .collect(Collectors.toList());
        List<User> users = this.userApplication.getByUserIds(userIds);
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getId, Function.identity()));

        List<Long> shopIds = orders.stream()
                .flatMap(order -> order.getItems().stream())
                .map(OrderItem::getShopId)
                .collect(Collectors.toList());
        List<Shop> shops = this.shopApplication.getByIds(shopIds);
        Map<Long, Shop> shopMap = shops.stream()
                .collect(Collectors.toMap(Shop::getId, Function.identity()));

        List<Long> productIds = orders.stream()
                .flatMap(order -> order.getItems().stream())
                .map(OrderItem::getProductId)
                .collect(Collectors.toList());
        List<Product> products = this.productApplication.getByIds(productIds);
        Map<Long, Product> productMap = products.stream()
                .collect(Collectors.toMap(Product::getId, Function.identity()));

        for (Order order : orders){
            OrderView orderView = new OrderView();
            orderViews.add(orderView);

            User user = userMap.get(order.getUserId());
            orderView.setUser(user);

            List<OrderItemView> orderItemViews = new ArrayList<>();
            orderView.setOrderItems(orderItemViews);
            for (OrderItem orderItem : order.getItems()){
                OrderItemView orderItemView = new OrderItemView();
                orderItemViews.add(orderItemView);

                Product product = productMap.get(orderItem.getProductId());
                orderItemView.setProduct(product);

                Shop shop = shopMap.get(orderItem.getShopId());
                orderItemView.setShop(shop);
            }
        }
        return orderViews;

    }
}
